﻿using Eholly.Communication.NamedPipe.Communicator;
using Eholly.Communication.NamedPipe.Endpoints;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.IO.Pipes;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Eholly.Communication.NamedPipe.Test
{
    public partial class MainForm : Form
    {
        private readonly INamedPipeCommunicator _communicator;
        private INamedPipeServer _server;
        private INamedPipeClient _client;

        public MainForm(INamedPipeCommunicator communicator)
        {
            _communicator = communicator;

            InitializeComponent();
        }

        /// <summary>
        /// 服务端：写
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void button1_Click(object sender, EventArgs e)
        {
            try
            {
                _server = await _communicator.CreateOrOpenServerAsync("communicator");
                NamedPipeResponse response = await _server.WriteMessageAsJsonAsync<Message<string>>(new NamedPipeAddressWrapper
                {
                    RequestAddress = new Communication.Endpoints.Address<NamedPipeAddress>
                    {
                        Value = new NamedPipeAddress
                        {
                            //RequestMessageName = "hello"
                        }
                    }
                }, new Message<string> { Content = "福建机械", Name = "hello" });
                //Debug.WriteLine(response.ToJson(_communicator.Config.JsonSerializerOptions));

                //_server.Over();
                //NamedPipeResponse<Message<string>> message = await _server.ReadMessageAsync<string>();
            }
            catch (System.Exception exp)
            {
                Debug.WriteLine(exp);
            }
        }

        /// <summary>
        /// 服务端：读(反序列化)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void button9_Click(object sender, EventArgs e)
        {
            try
            {
                _server = await _communicator.CreateOrOpenServerAsync("communicator");

                //NamedPipeResponse response = await _server.WriteMessageAsync<dynamic>(new NamedPipeAddressWrapper
                //{
                //    RequestAddress = new Communication.Endpoints.Address<NamedPipeAddress>
                //    {
                //        Value = new NamedPipeAddress
                //        {
                //            RequestMessageName = "hello"
                //        }
                //    }
                //}, new { Name = "国家", Country = "福建" });
                //Debug.WriteLine(response.ToJson());

                NamedPipeResponse<Message<string>> message = await _server.ReadMessageFromJsonAsync<Message<string>>();
                //Debug.WriteLine(message.ToJson(_communicator.Config.JsonSerializerOptions));

                if (message.IsSuccess && message.ReturnData.Name == NamedPipeCommunicationConsts.CommunicationEndedMessageName)
                {
                    _server.Dispose();
                }
                else
                {
                    Debug.WriteLine(message.Exception);
                }
            }
            catch (System.Exception exp)
            {
                Debug.WriteLine(exp);
            }
        }

        /// <summary>
        /// 服务端：直接读字符串
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void button15_Click(object sender, EventArgs e)
        {
            try
            {
                _server = await _communicator.CreateOrOpenServerAsync("communicator");

                NamedPipeResponse<string> response = await _server.ReadMessageAsync();

                if (response.IsSuccess && response.ReturnData == NamedPipeCommunicationConsts.CommunicationEndedMessageName)
                {
                    _server.Dispose();
                }
                else
                {
                    Debug.WriteLine(response.Exception);
                }
            }
            catch (System.Exception exp)
            {
                Debug.WriteLine(exp);
            }
        }

        /// <summary>
        /// 客户端1
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void button2_Click(object sender, EventArgs e)
        {
            try
            {
                _client = await _communicator.CreateOrOpenClientAsync(".", "communicator");

                //NamedPipeResponse response = await _client.WriteMessageAsync<string>(new NamedPipeAddressWrapper
                //{
                //    RequestAddress = new Communication.Endpoints.Address<NamedPipeAddress>
                //    {
                //        Value = new NamedPipeAddress
                //        {
                //            RequestMessageName = "hello"
                //        }
                //    }
                //}, "中国人");
                //Debug.WriteLine(response.ToJson(_communicator.Config.JsonSerializerOptions));

                NamedPipeResponse<Message<string>> message = await _client.ReadMessageFromJsonAsync<Message<string>>();
                //Debug.WriteLine(message.ToJson(_communicator.Config.JsonSerializerOptions));

                if (message.IsSuccess && message.ReturnData.Name == NamedPipeCommunicationConsts.CommunicationEndedMessageName)
                {
                    _client.Dispose();
                }
                else
                {
                    Debug.WriteLine(message.Exception);
                }
            }
            catch (System.Exception exp)
            {
                Debug.WriteLine(exp);
            }
        }

        /// <summary>
        /// 客户端2
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void button3_Click(object sender, EventArgs e)
        {
            _client = await _communicator.CreateOrOpenClientAsync(".", "communicator");

            NamedPipeResponse response = await _client.WriteMessageAsJsonAsync<string>(new NamedPipeAddressWrapper
            {
                RequestAddress = new Communication.Endpoints.Address<NamedPipeAddress>
                {
                    Value = new NamedPipeAddress
                    {
                        //RequestMessageName = "and you"
                    }
                }
            }, "日本人");
            //Debug.WriteLine(response.ToJson(_communicator.Config.JsonSerializerOptions));

            //_client.Over();
        }

        /// <summary>
        /// 服务端：连续写
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void button10_Click(object sender, EventArgs e)
        {
            _server = await _communicator.CreateOrOpenServerAsync("communicator");
            NamedPipeResponse response = await _server.WriteMessageAsJsonAsync<string>(new NamedPipeAddressWrapper
            {
                RequestAddress = new Communication.Endpoints.Address<NamedPipeAddress>
                {
                    Value = new NamedPipeAddress
                    {
                        //RequestMessageName = "hello"
                    }
                }
            }, "q 我们的祖国  大好河山啊  我更喜欢美女");
            //Debug.WriteLine(response.ToJson(_communicator.Config.JsonSerializerOptions));
        }
        /// <summary>
        /// 客户端3：连续读
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void button4_Click(object sender, EventArgs e)
        {
            _client = await _communicator.CreateOrOpenClientAsync(".", "communicator");
            NamedPipeResponse<Message<string>> message = await _client.ReadMessageFromJsonAsync<Message<string>>();
            //Debug.WriteLine(message.ToJson(_communicator.Config.JsonSerializerOptions));

            if (message.IsSuccess && message.ReturnData.Name == NamedPipeCommunicationConsts.CommunicationEndedMessageName)
            {
                _client.Dispose();
            }
            else
            {
                Debug.WriteLine(message.Exception);
            }
        }
        /// <summary>
        /// 继续读
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void button5_Click(object sender, EventArgs e)
        {
            _client = await _communicator.CreateOrOpenClientAsync(".", "communicator");
            NamedPipeResponse<Message<string>> message = await _client.ReadMessageFromJsonAsync<Message<string>>();
            //Debug.WriteLine(message.ToJson(_communicator.Config.JsonSerializerOptions));

            if (message.IsSuccess && message.ReturnData.Name == NamedPipeCommunicationConsts.CommunicationEndedMessageName)
            {
                _client.Dispose();
            }
            else
            {
                Debug.WriteLine(message.Exception);
            }
        }

        /// <summary>
        /// 多客户端同时连1
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void button6_Click(object sender, EventArgs e)
        {
            //_client = await _communicator.CreateOrOpenClientAsync(".", "communicator");
            //NamedPipeResponse<Message<dynamic>> message = await _client.ReadMessageAsync<dynamic>();
            //Debug.WriteLine("多客户端同时连1:" + message.ReturnData.ToJson());

            await Task.Run(() =>
            {
                using (var pipeClient = new NamedPipeClientStream(".", "communicator", PipeDirection.In))
                {
                    Debug.WriteLine("等待主进程指令...");

                    pipeClient.Connect();

                    using (var reader = new StreamReader(pipeClient))
                    {
                        string command = reader.ReadLine();
                        Debug.WriteLine($"收到主进程指令：{command}");

                        if (command == "Exit")
                        {
                            Debug.WriteLine("处理指令Exit，子程序退出。");
                        }
                        else
                        {

                        }
                    }
                }
            });
        }

        /// <summary>
        /// 多客户端同时连2
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void button7_Click(object sender, EventArgs e)
        {
            //_client = await _communicator.CreateOrOpenClientAsync(".", "communicator");
            //NamedPipeResponse<Message<dynamic>> message = await _client.ReadMessageAsync<dynamic>();
            //Debug.WriteLine("多客户端同时连2:" + message.ReturnData.ToJson());

            await Task.Run(() =>
            {
                using (var pipeClient = new NamedPipeClientStream(".", "communicator", PipeDirection.In))
                {
                    Debug.WriteLine("等待主进程指令...");

                    pipeClient.Connect();

                    using (var reader = new StreamReader(pipeClient))
                    {
                        string command = reader.ReadLine();
                        Debug.WriteLine($"收到主进程指令：{command}");

                        if (command == "Exit")
                        {
                            Debug.WriteLine("处理指令Exit，子程序退出。");
                        }
                        else
                        {

                        }
                    }
                }
            });
        }

        private async void button8_Click(object sender, EventArgs e)
        {
            for (var i = 0; i < 3; i++)
            {
                await Task.Run(() =>
                {
                    using (var pipeServer = new NamedPipeServerStream("communicator", PipeDirection.InOut))
                    {
                        // 等待子程序连接
                        pipeServer.WaitForConnection();

                        // 发送退出命令给子程序
                        using (var writer = new StreamWriter(pipeServer))
                        {
                            Debug.WriteLine("Xejen.Tools主程序发送退出命令");

                            writer.WriteLine("Exit");
                        }
                    }
                });
            }
        }

        /// <summary>
        /// 取消写入操作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void button11_Click(object sender, EventArgs e)
        {
            try
            {
                _client = await _communicator.CreateOrOpenClientAsync(".", "communicator");
                _client.ResetWrite();
            }
            catch (System.Exception exp)
            {
                Debug.WriteLine(exp);
            }
        }

        private async void button13_Click(object sender, EventArgs e)
        {
            try
            {
                _client = await _communicator.CreateOrOpenClientAsync(".", "communicator");
                _client.ResetRead();
            }
            catch (System.Exception exp)
            {
                Debug.WriteLine(exp);
            }
        }

        private async void button12_Click(object sender, EventArgs e)
        {
            try
            {
                _client = await _communicator.CreateOrOpenClientAsync(".", "communicator");
                await _client.EndMessageAsync();
                _client.Dispose();
            }
            catch (System.Exception exp)
            {
                Debug.WriteLine(exp);
            }
        }

        private async void button14_Click(object sender, EventArgs e)
        {
            try
            {
                _server = await _communicator.CreateOrOpenServerAsync("communicator");
                await _server.EndMessageAsync();
                _server.Dispose();
            }
            catch (System.Exception exp)
            {
                Debug.WriteLine(exp);
            }
        }

        /// <summary>
        /// 测试异常客户端
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button16_Click(object sender, EventArgs e)
        {
            Task.Run(() =>
            {
                while (true)
                {
                    try
                    {
                        using (NamedPipeClientStream pipeClient = new NamedPipeClientStream(".", "communicator", PipeDirection.InOut))
                        {
                            pipeClient.Connect();

                            Debug.WriteLine("Client connected.");

                            using (StreamReader reader = new StreamReader(pipeClient))
                            using (StreamWriter writer = new StreamWriter(pipeClient))
                            {
                                if (pipeClient.IsConnected)
                                {
                                    if (true)
                                    {
                                        Thread.Sleep(10);
                                        continue;
                                    }

                                    if (pipeClient.CanWrite)
                                    {
                                        string message = "CanCollect";

                                        writer.WriteLine(message);

                                        writer.Flush();
                                    }
                                }
                            }
                        }
                    }
                    catch (System.Exception exp)
                    {
                        Debug.WriteLine(exp);
                    }
                }
            });
        }

        /// <summary>
        /// 测试异常客户端
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void button17_Click(object sender, EventArgs e)
        {
            _server = await _communicator.CreateOrOpenServerAsync("communicator");

            NamedPipeResponse<string> response0 = await _server.ReadMessageAsync();
            if (!response0.IsSuccess)
            {
                Debug.WriteLine(response0.Exception);
                _server.Dispose();
                return;
            }
            if (response0.ReturnData != "CanCollect")
            {
                _server.Dispose();
                return;
            }
        }
    }
}
